import { defineStore } from "pinia";
import { getToken, removeToken, setToken } from "../utils/token-utils";
import type { UserInfoState } from "./interface";
import { ElMessage } from "element-plus";
import { staticRoutes, allAsyncRoutes } from "@/router/routes";
import { reqLogin, reqLogout, reqUserInfo } from "@/api/user";
import type { RouteRecordRaw } from "vue-router";

//封装一个函数,用来根据用户的权限过滤异步路由表
//接受两个参数,一个是异步路由表 一个是用户权限的路由数组
function filterAsyncRoutes(
	allAsyncRoutes: Array<RouteRecordRaw>,
	routeNames: string[]
) {
	//逻辑就是根据用户的路由数组的值,过滤异步路由,得到过出来的符合条件的异步路由中的路由组成的数组
	return allAsyncRoutes.filter((item) => {
		//判断当前1级路由item的name有没有在用户权限路由数组中出现
		if (routeNames.includes(item.name as string)) {
			//递归一定要写条件,否则会出现栈溢出
			//没有子组件就停止
			if (item.children?.length) {
				//如果当前的1级路由确实出现在了当前用户的权限路由数组中,则还要看当前符合条件的1级路由中二级路由有哪些也是符合条件的
				//把二级路由过滤的结果得到,作为一级的路由要携带走的child子路由
				item.children = filterAsyncRoutes(
					item.children as RouteRecordRaw[],
					routeNames
				);
			}

			//filter只有在内部函数返回true的时候,才会进行过滤出来
			return true;
		}
	});
}

/**
 * 用户信息
 * @methods setUserInfos 设置用户信息
 */
export const useUserInfoStore = defineStore("userInfo", {
	state: (): UserInfoState => ({
		token: getToken() as string,
		userInfo: {
			routes: [], //当前用户的路由权限(菜单权限)
			buttons: [], //当前用户的按钮权限
			roles: [], //当前用户的角色
			name: "",
			avatar: "",
		},
		menuRoutes: staticRoutes,
	}),

	actions: {
		//登录的方法
		/* 
      分析login登录需要做的事情
        - 发送请求,得到token
        - 把token保存在state中
        - token是要做数据持久化的,所以在localStorage中也保存一份token
    */
		async login(username: string, password: string) {
			const result = await reqLogin(username, password);
			this.token = result.token;
			setToken(result.token);
		},

		/*
      获取用户信息的逻辑
        - 发送请求
        - 拿到用户信息并交给state保管

    */
		async getInfo() {
			const userInfo = await reqUserInfo();
			// console.log(userInfo);
			this.userInfo = userInfo;

			//此时拿到用户的路由权限数组 routes
			//也可以拿到异步路由表
			//我们就进行对比,看一下异步路由表中哪些路由符合权限数组,如果符合,则把这个异步路由添加到静态路由中
			const re = filterAsyncRoutes(allAsyncRoutes, userInfo.routes);
			console.log(re, "re");
		},

		/* 
      退出登录逻辑
        - 发送退出登录请求
        - 清空本地数据
    */
		async logout() {
			await reqLogout();
			//数据和方法都在当前的store对象上,this指向store对象
			this.reset();
		},

		reset() {
			// 删除local中保存的token
			removeToken();
			// 提交重置用户信息的mutation
			this.token = "";
			this.userInfo = {
				routes: [],
				buttons: [],
				roles: [],
				name: "",
				avatar: "",
			};
		},
	},
});
